/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.util.ant; import com.liferay.portal.kernel.util.CharPool; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.SystemProperties; import com.liferay.portal.kernel.util.Validator; import com.liferay.util.xml.Dom4jUtil; import com.liferay.util.xml.XMLSafeReader; import java.io.File; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.TreeMap; import org.apache.axis.tools.ant.wsdl.Java2WsdlAntTask; import org.apache.axis.tools.ant.wsdl.NamespaceMapping; import org.apache.axis.tools.ant.wsdl.Wsdl2javaAntTask; import org.apache.tools.ant.Project; import org.apache.tools.ant.types.Path; import org.dom4j.Attribute; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.SAXReader; /** * @author Brian Wing Shun Chan */ public class Java2WsddTask { public static String[] generateWsdd( String className, String classPath, String serviceName) throws Exception { // Create temp directory java.nio.file.Path tempDirPath = Files.createTempDirectory( Paths.get(SystemProperties.get(SystemProperties.TMP_DIR)), null); File tempDir = tempDirPath.toFile(); tempDir.mkdir(); // axis-java2wsdl String wsdlFileName = tempDir + "/service.wsdl"; int pos = className.lastIndexOf("."); String packagePath = className.substring(0, pos); String[] packagePaths = StringUtil.split(packagePath, '.'); String namespace = "urn:"; for (int i = packagePaths.length - 1; i >= 0; i--) { namespace += packagePaths[i]; if (i > 0) { namespace += "."; } } String location = "http://localhost/services/" + serviceName; String mappingPackage = packagePath.substring( 0, packagePath.lastIndexOf(".")) + ".ws"; Project project = AntUtil.getProject(); Java2WsdlAntTask java2Wsdl = new Java2WsdlAntTask(); NamespaceMapping mapping = new NamespaceMapping(); mapping.setNamespace(namespace); mapping.setPackage(mappingPackage); java2Wsdl.setProject(project); java2Wsdl.setClassName(className); if (Validator.isNotNull(classPath)) { java2Wsdl.setClasspath(new Path(project, classPath)); } java2Wsdl.setOutput(new File(wsdlFileName)); java2Wsdl.setLocation(location); java2Wsdl.setNamespace(namespace); java2Wsdl.addMapping(mapping); java2Wsdl.execute(); // axis-wsdl2java Wsdl2javaAntTask wsdl2Java = new Wsdl2javaAntTask(); wsdl2Java.setProject(project); wsdl2Java.setURL(wsdlFileName); wsdl2Java.setOutput(tempDir); wsdl2Java.setServerSide(true); wsdl2Java.setTestCase(false); wsdl2Java.setVerbose(false); wsdl2Java.execute(); // Get content String packagePathWithSlashes = StringUtil.replace( packagePath, CharPool.PERIOD, CharPool.SLASH); File deployFile = new File( tempDir + "/" + packagePathWithSlashes + "/deploy.wsdd"); String deployContent = new String( Files.readAllBytes(deployFile.toPath())); deployContent = StringUtil.replace( deployContent, packagePath + "." + serviceName + "SoapBindingImpl", className); deployContent = _format(deployContent); File undeployFile = new File( tempDir + "/" + packagePathWithSlashes + "/undeploy.wsdd"); String undeployContent = new String( Files.readAllBytes(undeployFile.toPath())); undeployContent = _format(undeployContent); // Delete temp directory DeleteTask.deleteDirectory(tempDir); return new String[] {deployContent, undeployContent}; } private static void _addElements( Element element, Map<String, Element> elements) { for (Map.Entry<String, Element> entry : elements.entrySet()) { Element childElement = entry.getValue(); element.add(childElement); } } private static String _format(String content) throws Exception { content = _stripComments(content); SAXReader saxReader = new SAXReader(); Document document = saxReader.read(new XMLSafeReader(content)); Element rootElement = document.getRootElement(); Element serviceElement = rootElement.element("service"); Map<String, Element> arrayMappingElements = new TreeMap<>(); Map<String, Element> typeMappingElements = new TreeMap<>(); Map<String, Element> operationElements = new TreeMap<>(); Map<String, Element> parameterElements = new TreeMap<>(); List<Element> elements = serviceElement.elements(); for (Element element : elements) { String elementName = element.getName(); if (elementName.equals("arrayMapping")) { element.detach(); arrayMappingElements.put(_formattedString(element), element); } else if (elementName.equals("operation")) { element.detach(); List<Element> parameters = element.elements("parameter"); StringBundler sb = new StringBundler(2 * parameters.size() + 2); String name = element.attributeValue("name"); sb.append(name); sb.append("_METHOD_"); for (Element parameterElement : parameters) { String type = parameterElement.attributeValue("type"); sb.append(type); sb.append("_PARAMETER_"); } operationElements.put(sb.toString(), element); } else if (elementName.equals("parameter")) { element.detach(); String name = element.attributeValue("name"); if (name.equals("allowedMethods")) { Attribute valueAttribute = element.attribute("value"); String[] values = StringUtil.split( valueAttribute.getValue(), CharPool.SPACE); Arrays.sort(values); valueAttribute.setValue( StringUtil.merge(values, StringPool.SPACE)); } else if (name.equals("schemaUnqualified")) { Attribute valueAttribute = element.attribute("value"); String[] values = StringUtil.split( valueAttribute.getValue()); Arrays.sort(values); valueAttribute.setValue(StringUtil.merge(values)); } parameterElements.put(name, element); } else if (elementName.equals("typeMapping")) { element.detach(); typeMappingElements.put(_formattedString(element), element); } } _addElements(serviceElement, arrayMappingElements); _addElements(serviceElement, typeMappingElements); _addElements(serviceElement, operationElements); _addElements(serviceElement, parameterElements); content = StringUtil.replace( _formattedString(document), "\"/>", "\" />"); return content; } private static String _formattedString(Node node) throws Exception { return Dom4jUtil.toString(node); } private static String _stripComments(String text) { return StringUtil.stripBetween(text, "<!--", "-->"); } }